package de.wbh.gwt.form.layouter.java.server;

public class Sobel {

	int[] input;
	int[] output;
	float[] template = { -1, 0, 1, -2, 0, 2, -1, 0, 1 };;
	int progress;
	int templateSize = 3;
	int width;
	int height;
	double[] direction;

	public double[] getDirection() {
		return this.direction;
	}

	public int getProgress() {
		return this.progress;
	}

	public void init(int[] original, int widthIn, int heightIn) {
		this.width = widthIn;
		this.height = heightIn;
		this.input = new int[this.width * this.height];
		this.output = new int[this.width * this.height];
		this.direction = new double[this.width * this.height];
		this.input = original;
	}

	public int[] process() {
		float[] GY = new float[this.width * this.height];
		float[] GX = new float[this.width * this.height];
		int[] total = new int[this.width * this.height];
		this.progress = 0;
		int sum = 0;
		int max = 0;

		for (int x = (this.templateSize - 1) / 2; x < this.width - (this.templateSize + 1) / 2; x++) {
			this.progress++;
			for (int y = (this.templateSize - 1) / 2; y < this.height - (this.templateSize + 1) / 2; y++) {
				sum = 0;

				for (int x1 = 0; x1 < this.templateSize; x1++) {
					for (int y1 = 0; y1 < this.templateSize; y1++) {
						int x2 = (x - (this.templateSize - 1) / 2 + x1);
						int y2 = (y - (this.templateSize - 1) / 2 + y1);
						float value = (this.input[y2 * this.width + x2] & 0xff) * (this.template[y1 * this.templateSize + x1]);
						sum += value;
					}
				}
				GY[y * this.width + x] = sum;
				for (int x1 = 0; x1 < this.templateSize; x1++) {
					for (int y1 = 0; y1 < this.templateSize; y1++) {
						int x2 = (x - (this.templateSize - 1) / 2 + x1);
						int y2 = (y - (this.templateSize - 1) / 2 + y1);
						float value = (this.input[y2 * this.width + x2] & 0xff) * (this.template[x1 * this.templateSize + y1]);
						sum += value;
					}
				}
				GX[y * this.width + x] = sum;

			}
		}
		for (int x = 0; x < this.width; x++) {
			for (int y = 0; y < this.height; y++) {
				total[y * this.width + x] = (int) Math.sqrt(GX[y * this.width + x] * GX[y * this.width + x] + GY[y * this.width + x] * GY[y * this.width + x]);
				this.direction[y * this.width + x] = Math.atan2(GX[y * this.width + x], GY[y * this.width + x]);
				if (max < total[y * this.width + x]) {
					max = total[y * this.width + x];
				}
			}
		}
		float ratio = (float) max / 255;
		for (int x = 0; x < this.width; x++) {
			for (int y = 0; y < this.height; y++) {
				sum = (int) (total[y * this.width + x] / ratio);
				this.output[y * this.width + x] = 0xff000000 | (sum << 16 | sum << 8 | sum);
			}
		}
		this.progress = this.width;
		return this.output;
	}

	public void Sobel() {
		this.progress = 0;
	}

}
